﻿// -------------------------------------------------------------------------
//    @FileName         :    NFHeroPart.cpp
//    @Author           :    gaoyi
//    @Date             :    24-8-30
//    @Email            :    445267987@qq.com
//    @Module           :    NFHeroPart
//
// -------------------------------------------------------------------------

#include "NFHeroPart.h"

#include "NFLogicCommon/BagPage/NFBagPage.h"
#include <NFHeroUtil.h>
#include <NFPlayer.h>
#include <NFServicePackage.h>
#include <DescStore/ActorDesc.h>

#include "NFHeroAttrCalcFactory.h"
#include "NFServiceHero.h"
#include "proto_db.pb.h"
#include "NFLogicCommon/NFAttr.h"

NFHeroPart::NFHeroPart()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFHeroPart::~NFHeroPart()
{
}

int NFHeroPart::CreateInit()
{
    m_bIsInited = false;
    m_iTempAttrTick = 0;
    m_iPreViewBranch = 0; //preview skill awake branch
    return 0;
}

int NFHeroPart::ResumeInit()
{
    return 0;
}

int NFHeroPart::LoadFromDB(const proto_ff::tbRoleDetail* pDBData)
{
    auto pPlayer = GetPlayer();
    CHECK_NULL(0, pPlayer);

    auto& srcHero = pDBData->role_base_data().hero();
    m_hero_data.FromPb(srcHero);


    memset(m_hero_data.attr_list, 0, sizeof(m_hero_data.attr_list));
    for (int k = 0; k < srcHero.attr_list_size(); ++k)
    {
        const proto_ff::CSAttr& attr = srcHero.attr_list(k);
        proto_ff::AttrType iAttrType = attr.type();
        if (proto_ff::AttrType_IsValid(iAttrType))
        {
            m_hero_data.attr_list[iAttrType].type = (AttrType)iAttrType;
            m_hero_data.attr_list[iAttrType].value = attr.value();
        }
    }

    if (m_hero_data.attr_list[proto_ff::EN_ATTR_HP].value <= 0)
    {
        m_hero_data.attr_list[proto_ff::EN_ATTR_HP].value = 1;
    }

    NFBagPage* pBagPage = NFServicePackage::GetBagPage(pPlayer, EN_BPT_DRESSED_ITEM);
    CHECK_NULL(m_roleId, pBagPage);
    for (int e = 0; e < (int)ARRAYSIZE(m_hero_data.equip_list); ++e)
    {
        if (m_hero_data.equip_list[e] == 0)
            continue;

        NFGridItem* pItem = pBagPage->GetItemByUUID(m_hero_data.equip_list[e]);
        if (pItem == nullptr)
        {
            m_hero_data.equip_list[e] = 0;
        }
    }

    for (int e = 0; e < (int)ARRAYSIZE(m_hero_data.buff_equip_list); ++e)
    {
        if (m_hero_data.buff_equip_list[e] == 0)
            continue;

        NFGridItem* pItem = pBagPage->GetItemByUUID(m_hero_data.buff_equip_list[e]);
        if (pItem == nullptr)
        {
            m_hero_data.buff_equip_list[e] = 0;
        }
    }

    NFHeroAttrCalcFactory::Recalc(&m_hero_data, pPlayer);

    LOGSVR_INFO(pDBData->role_base_data().hero().DebugString());
    return 0;
}

int NFHeroPart::InitConfig(proto_ff::tbRoleDetail* pDbData, const RoleOne& stRoleOne)
{
    int iRetCode = 0;
    auto pHero = pDbData->mutable_role_base_data()->mutable_hero();
    CHECK_NULL(0, pDbData);
    CHECK_NULL(0, pHero);

    auto pPlayer = GetPlayer();
    CHECK_NULL(0, pPlayer);

    int iActorId = stRoleOne.actor_id;

    auto pActorDesc = ActorDesc::Instance()->GetDesc(iActorId);
    CHECK_NULL(0, pActorDesc);

    HeroOne stHeroOne;
    iRetCode = NFHeroUtil::InitHero(stHeroOne, pActorDesc);
    CHECK_ERR(pPlayer->GetRoleID(), iRetCode, "NFHeroUtil::InitHero failed. actor_id:{}", iActorId);

    iRetCode = NFHeroAttrCalcFactory::Calc(&stHeroOne, pPlayer);
    CHECK_ERR(pPlayer->GetRoleID(), iRetCode, "NFHeroAttrCalcFactory::Calc failed.");

    NFHeroUtil::InitHpMp(stHeroOne);

    stHeroOne.ToPb(pHero);

    return 0;
}

int NFHeroPart::SaveDB(proto_ff::tbRoleDetail* pDBData)
{
    auto pPlayerHeroData = pDBData->mutable_role_base_data()->mutable_hero();
    m_hero_data.ToPb(pPlayerHeroData);
    pPlayerHeroData->clear_attr_list();
    proto_ff::CSAttr* pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_LEVEL);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_LEVEL].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_EXP_SUM);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_EXP_SUM].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_HP_RESERVE);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_HP_RESERVE].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_MP_RESERVE);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_MP_RESERVE].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_HP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_HP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_MP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_MP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_MAX_HP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_MAX_HP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_MAX_MP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_MAX_MP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_EP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_EP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_MAX_EP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_MAX_EP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_FREEZE_FP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_FREEZE_FP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_ACTIVATE_FP);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_ACTIVATE_FP].value);

    pAttr = pPlayerHeroData->add_attr_list();
    pAttr->set_type(proto_ff::EN_ATTR_CITY_MOV_SPD);
    pAttr->set_value(m_hero_data.attr_list[proto_ff::EN_ATTR_CITY_MOV_SPD].value);
    return 0;
}

uint32_t NFHeroPart::GetCityHero() const
{
    return m_hero_data.id;
}

uint32_t NFHeroPart::GetHeroID() const
{
    return m_hero_data.id;
}

bool NFHeroPart::IsInit() const
{
    return m_bIsInited;
}

const HeroOne* NFHeroPart::GetHero() const
{
    return &m_hero_data;
}

HeroOne* NFHeroPart::GetHero()
{
    return &m_hero_data;
}

int NFHeroPart::ClearHero()
{
    m_hero_data.Init();
    return 0;
}

int NFHeroPart::MakePlayerDataCS(proto_ff::Proto_CSGetRoleRsp* pCSGetRoleRsp)
{
    m_hero_data.ToPb(pCSGetRoleRsp->mutable_hero_data()->add_hero_list());
    return 0;
}

int NFHeroPart::MakeCityPlayerData(proto_ff::CityRoleInfo* pGCCityRoleInfo)
{
    m_hero_data.ToPb(pGCCityRoleInfo->mutable_hero());
    return 0;
}

int NFHeroPart::SaveRoleSimpleInfo(proto_ff::Proto_RoleSimpleInfo* pDbData)
{
    pDbData->set_player_id(m_hero_data.id);
    return 0;
}

int64_t NFHeroPart::GetAttr(int attrType)
{
    int64_t value = 0;
    int iRetCode = GetAttrValue(m_hero_data, attrType, value);
    CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "get attr value error, attrType:{}", attrType);
    return value;
}

int NFHeroPart::AddAttr(int attrType, int64_t llValue, int iReason, int param)
{
    int64_t oldValue = 0;
    int iRetCode = GetAttrValue(m_hero_data, attrType, oldValue);
    CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "get attr value error, attrType:{}", attrType);

    iRetCode = AddAttrValue(m_hero_data, attrType, llValue);
    CHECK_ERR(m_roleId, iRetCode, "add attr value error, attrType:{} llValue:{}", attrType, llValue);

    int64_t newValue = 0;
    iRetCode = GetAttrValue(m_hero_data, attrType, newValue);
    CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "get attr value error, attrType:{}", attrType);

    if (oldValue != newValue)
    {
        iRetCode = OnAttrChange(attrType, oldValue, newValue, iReason, param);
        CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "OnAttrChange error, attrType:{} oldValue:{}, newValue:{}, iReason:{}, param:{}", attrType, oldValue, newValue, iReason, param);
    }
    return 0;
}

int NFHeroPart::SetAttr(int attrType, int64_t llValue, int iReason, int param)
{
    int64_t oldValue = 0;
    int iRetCode = GetAttrValue(m_hero_data, attrType, oldValue);
    CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "get attr value error, attrType:{}", attrType);

    if (oldValue == llValue)
    {
        return 0;
    }

    iRetCode = SetAttrValue(m_hero_data, attrType, llValue);
    CHECK_ERR(m_roleId, iRetCode, "add attr value error, attrType:{} llValue:{}", attrType, llValue);

    int64_t newValue = 0;
    iRetCode = GetAttrValue(m_hero_data, attrType, newValue);
    CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "get attr value error, attrType:{}", attrType);

    if (oldValue != newValue)
    {
        iRetCode = OnAttrChange(attrType, oldValue, newValue, iReason, param);
        CHECK_ERR_RE_VAL(m_roleId, iRetCode, 0, "OnAttrChange error, attrType:{} oldValue:{}, newValue:{}, iReason:{}, param:{}", attrType, oldValue, newValue, iReason, param);
    }
    return 0;
}

int NFHeroPart::OnAttrChange(int attrType, int64_t llOldValue, int64_t llNewValue, int iReason, int param)
{
    return 0;
}
